package java8.exercise.demo.collectors;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class CollectorsMain {

    public static void main(String[] args) {
        bfAveragingDouble();
    }

    /**
     * averagingDouble
     * 将流中的所有元素视为 double 类型并计算他们的平均值
     * 该方法返回的是同一个 Collectors 实例，因此可以进行链式操作。
     * averagingDouble() 接受一个参数，这个参数是一个 lambda 表达式，用于对所有的元素执行一个 map 操作。
     */
    public static void bfAveragingDouble() {
        List<Integer> list = Arrays.asList(1, 2, 3, 4);
        Double dbList = list.stream().collect(Collectors.averagingDouble(one -> one * 2));
        System.out.println(dbList);
    }

    /**
     * Collectors.averagingInt() 方法和 Collectors.averagingDouble() 一样，
     * 不同的是它把流中的所有元素看成是 int 类型，并返回一个浮点类型的平均值
     */
    public static void bfAveragingInt() {
        List<Integer> list = Arrays.asList(1, 2, 3, 4);
        Double dbList = list.stream().collect(Collectors.averagingInt(one -> one * 3));
        System.out.println(dbList);
    }

    /**
     * Collectors.collectingAndThen() 函数应该最像 map and reduce 了，
     * 它可接受两个参数，第一个参数用于 reduce 操作，而第二参数用于 map 操作。
     * 也就是，先把流中的所有元素传递给第二个参数，然后把生成的集合传递给第一个参数来处理。
     */
    public static void bfCollectingAndThen() {
        List<Integer> list = Arrays.asList(1, 2, 3, 4);
        Double result = list.stream().collect(Collectors.collectingAndThen(Collectors.averagingLong(v -> v * 2), s -> s * s));
        System.out.println(result);
    }

}
